
package com.mancj.slideup;

import ohos.agp.components.Component;
import ohos.multimodalinput.event.TouchEvent;

/**
 * Horizontal touch consumer
 *
 * @author pa.gulko zTrap (12.07.2017)
 */
class HorizontalTouchConsumer extends TouchConsumer {
    /**
     * The constant M going to start
     */
    private boolean mGoingToStart = false;
    /**
     * The constant M going to end
     */
    private boolean mGoingToEnd = false;

    /**
     * Horizontal touch consumer
     *
     * @param builder            builder
     * @param notifier           notifier
     * @param animationProcessor animation processor
     */
    HorizontalTouchConsumer(SlideUpBuilder builder, LoggerNotifier notifier, AnimationProcessor animationProcessor) {
        super(builder, notifier, animationProcessor);
    }

    /**
     * Consume end to start boolean
     *
     * @param touchedView touched view
     * @param event       event
     * @return the boolean
     */
    boolean consumeEndToStart(Component touchedView, TouchEvent event) {
        float touchedArea = event.getPointerPosition(0).getX();
        switch (event.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                mViewWidth = mBuilder.mSliderView.getWidth();
                mStartPositionX = event.getPointerScreenPosition(0).getX();
                mViewStartPositionX = mBuilder.mSliderView.getTranslationX();
                mCanSlide = touchFromAlsoSlide(touchedView, event);
                mCanSlide |= getStart() + mBuilder.mTouchableArea >= (touchedArea - mBuilder.locationOnScreenX);
                break;
            case TouchEvent.POINT_MOVE:
                float difference = event.getPointerScreenPosition(0).getX() - mStartPositionX;
                float moveTo = mViewStartPositionX + difference;
                float percents = moveTo * 100 / mBuilder.mSliderView.getWidth();
                calculateDirection(event);

                if (moveTo > 0 && mCanSlide) {
                    mNotifier.notifyPercentChanged(percents);
                    mBuilder.mSliderView.setTranslationX(moveTo);
                }
                break;
            case TouchEvent.PRIMARY_POINT_UP:
                float slideAnimationFrom = mBuilder.mSliderView.getTranslationX();
                if (slideAnimationFrom == mViewStartPositionX) {
                    return !Internal.isUpEventInView(mBuilder.mSliderView, event, mBuilder.locationOnScreenX, mBuilder.locationOnScreenY);
                }
                boolean scrollableAreaConsumed = mBuilder.mSliderView.getTranslationX() > mBuilder.mSliderView.getWidth() / 5;

                if (scrollableAreaConsumed && mGoingToEnd) {
                    mAnimationProcessor.setValuesAndStart(slideAnimationFrom, mBuilder.mSliderView.getWidth());
                } else {
                    mAnimationProcessor.setValuesAndStart(slideAnimationFrom, 0);
                }
                mCanSlide = true;
                break;
        }
        mPrevPositionY = event.getPointerScreenPosition(0).getY();
        mPrevPositionX = event.getPointerScreenPosition(0).getX();
        return true;
    }

    /**
     * Consume start to end boolean
     *
     * @param touchedView touched view
     * @param event       event
     * @return the boolean
     */
    boolean consumeStartToEnd(Component touchedView, TouchEvent event) {
        float touchedArea = event.getPointerPosition(0).getX();
        switch (event.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                mViewWidth = mBuilder.mSliderView.getWidth();
                mStartPositionX = event.getPointerScreenPosition(0).getX();
                mViewStartPositionX = mBuilder.mSliderView.getTranslationX();
                mCanSlide = touchFromAlsoSlide(touchedView, event);
                mCanSlide |= getEnd() - mBuilder.mTouchableArea >= touchedArea;
                break;
            case TouchEvent.POINT_MOVE:
                float difference = event.getPointerScreenPosition(0).getX() - mStartPositionX;
                float moveTo = mViewStartPositionX + difference;
                float percents = moveTo * 100 / -mBuilder.mSliderView.getWidth();
                calculateDirection(event);

                if (moveTo < 0 && mCanSlide) {
                    mNotifier.notifyPercentChanged(percents);
                    mBuilder.mSliderView.setTranslationX(moveTo);
                }
                break;
            case TouchEvent.PRIMARY_POINT_UP:
                float slideAnimationFrom = -mBuilder.mSliderView.getTranslationX();
                if (slideAnimationFrom == mViewStartPositionX) {
                    return !Internal.isUpEventInView(mBuilder.mSliderView, event, mBuilder.locationOnScreenX, mBuilder.locationOnScreenY);
                }
                boolean scrollableAreaConsumed = mBuilder.mSliderView.getTranslationX() < -mBuilder.mSliderView.getWidth() / 5;

                if (scrollableAreaConsumed && mGoingToStart) {
                    mAnimationProcessor.setValuesAndStart(-slideAnimationFrom, -mBuilder.mSliderView.getWidth());
                } else {
                    mAnimationProcessor.setValuesAndStart(-slideAnimationFrom, 0);
                }
                mCanSlide = true;
                break;
        }
        mPrevPositionY = event.getPointerScreenPosition(0).getY();
        mPrevPositionX = event.getPointerScreenPosition(0).getX();
        return true;
    }

    /**
     * Calculate direction *
     *
     * @param event event
     */
    private void calculateDirection(TouchEvent event) {
        mGoingToStart = mPrevPositionX > event.getPointerScreenPosition(0).getX();
        mGoingToEnd = mPrevPositionX < event.getPointerScreenPosition(0).getX();
    }
}
